/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package com.xiashitech.agent.instrumentation.redis.redisson.v317.inst;

import com.xiashitech.agent.cache.status.CacheStatus;
import com.xiashitech.agent.instrumentation.redis.redisson.XSCompletableFutureWrapper;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

import java.util.concurrent.CompletableFuture;

import static net.bytebuddy.matcher.ElementMatchers.*;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

public class XSRedisCommandDataInstrumentation implements TypeInstrumentation {

    @Override
    public ElementMatcher<TypeDescription> typeMatcher() {
        return namedOneOf(
                "org.redisson.client.protocol.CommandData", "org.redisson.client.protocol.CommandsData");
    }

    @Override
    public void transform(TypeTransformer transformer) {
        transformer.applyAdviceToMethod(
                isConstructor().and(takesArgument(0, CompletableFuture.class)),
                this.getClass().getName() + "$WrapCompletableFutureAdvice");
    }

    @SuppressWarnings("unused")
    public static class WrapCompletableFutureAdvice {

        @Advice.OnMethodEnter(suppress = Throwable.class)
        public static void onEnter(
                @Advice.Argument(value = 0, readOnly = false) CompletableFuture<?> completableFuture) {
            if(CacheStatus.cannotRun()) {
                return;
            }
            completableFuture = XSCompletableFutureWrapper.wrap(completableFuture);
        }
    }
}
